{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Comparing qubits\n",
    "In this exercise we will show a real comparison between the different qubits in one of the machines.\n",
    "We will run the same Bell state quantum program on three different setups:  \n",
    "- an ideal quantum computer (qasm_simulator)\n",
    "- the “best” and the “worst” qubit pair on a five qubit least busy IBM Q machine  \n",
    "\n",
    "We will print and plot the end result to compare the ideal result (|00> and |11> at 50%) with the real results (A probabilistic mix of |00>, |01>, |10>, and |11>) to illustrate how today’s quantum computers still have a little way to go. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Let's start by importing the IBMQ method and load our account."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit import QuantumCircuit, IBMQ, Aer,  ClassicalRegister, QuantumRegister, execute\n",
    "from qiskit.tools.monitor import job_monitor\n",
    "from qiskit.visualization import plot_histogram\n",
    "\n",
    "IBMQ.load_account()\n",
    "provider = IBMQ.get_provider()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Then, let's pick the least busy available backend for our exercise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit.providers.ibmq import least_busy\n",
    "backend = least_busy(provider.backends(operational=True, simulator=False))\n",
    "\n",
    "print(\"Selected backend:\",backend.status().backend_name)\n",
    "print(\"Number of qubits(n_qubits):\", backend.configuration().n_qubits)\n",
    "print(\"Pending jobs:\", backend.status().pending_jobs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Pull out the best and worst cx-gates performance information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "gates=backend.properties().gates\n",
    "\n",
    "gate_type = \"cx\"\n",
    "cx_best_worst = [[[0,0],1],[[0,0],0]]\n",
    "for n in range (0, len(gates)):\n",
    "    if gates[n].gate == gate_type:\n",
    "        if gate_type == \"cx\":\n",
    "            print(gates[n].name, \":\", gates[n].parameters[0].name,\"=\", gates[n].parameters[0].value)\n",
    "            if cx_best_worst[0][1]>gates[n].parameters[0].value:\n",
    "                cx_best_worst[0][1]=gates[n].parameters[0].value\n",
    "                cx_best_worst[0][0]=gates[n].qubits\n",
    "            if cx_best_worst[1][1]<gates[n].parameters[0].value:\n",
    "                cx_best_worst[1][1]=gates[n].parameters[0].value\n",
    "                cx_best_worst[1][0]=gates[n].qubits\n",
    "        else:\n",
    "            print(gates[n].gate, gates[n].parameters[0].name,gates[n].parameters[0].value)\n",
    "\n",
    "print(\"Best cx gate:\", cx_best_worst[0][0], \",\", round(cx_best_worst[0][1]*100,3),\"%\")\n",
    "print(\"Worst cx gate:\", cx_best_worst[1][0], \",\", round(cx_best_worst[1][1]*100,3),\"%\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Create a quantum circuit for the selected backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "q1 = QuantumRegister(backend.configuration().n_qubits)\n",
    "c1 = ClassicalRegister(backend.configuration().n_qubits)\n",
    "qc_best = QuantumCircuit(q1, c1)\n",
    "qc_worst = QuantumCircuit(q1, c1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Create the best Bell circuit for the backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "qc_best.h(q1[cx_best_worst[0][0][0]])\n",
    "qc_best.cx(q1[cx_best_worst[0][0][0]], q1[cx_best_worst[0][0][1]])\n",
    "qc_best.measure(q1[cx_best_worst[0][0][0]], c1[0])\n",
    "qc_best.measure(q1[cx_best_worst[0][0][1]], c1[1])\n",
    "print(\"Best CX:\")\n",
    "print(qc_best)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Create the worst Bell circuit for the backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "qc_worst.h(q1[cx_best_worst[1][0][0]])\n",
    "qc_worst.cx(q1[cx_best_worst[1][0][0]], q1[cx_best_worst[1][0][1]])\n",
    "qc_worst.measure(q1[cx_best_worst[1][0][0]], c1[0])\n",
    "qc_worst.measure(q1[cx_best_worst[1][0][1]], c1[1])\n",
    "\n",
    "print(\"Worst CX:\")\n",
    "print(qc_worst)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Run the best and worst circuits on backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "job_best = execute(qc_best, backend, shots=1000)\n",
    "job_monitor(job_best)\n",
    "job_worst = execute(qc_worst, backend, shots=1000)\n",
    "job_monitor(job_worst)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Run a benchmark Bell circuit on the simulator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "q = QuantumRegister(backend.configuration().n_qubits)\n",
    "c = ClassicalRegister(backend.configuration().n_qubits)\n",
    "qc = QuantumCircuit(q, c)\n",
    "\n",
    "qc.h(q[0])\n",
    "qc.cx(q[0], q[1])\n",
    "qc.measure(q[0], c[0])\n",
    "qc.measure(q[1], c[1])\n",
    "\n",
    "backend_sim = Aer.get_backend('qasm_simulator')\n",
    "job_sim = execute(qc, backend_sim)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Print the results for the best, worst, and baseline qubit pair."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "best_result = job_best.result()\n",
    "counts_best  = best_result.get_counts(qc_best)\n",
    "print(\"Best qubit pair:\")\n",
    "print(counts_best)\n",
    "\n",
    "worst_result = job_worst.result()\n",
    "counts_worst  = worst_result.get_counts(qc_worst)\n",
    "print(\"Worst qubit pair:\")\n",
    "print(counts_worst)\n",
    "\n",
    "sim_result = job_sim.result()\n",
    "counts_sim  = sim_result.get_counts(qc)\n",
    "print(\"Simulated baseline:\")\n",
    "print(counts_sim)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Plot the results in a diagram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "plot_histogram([counts_worst, counts_best, counts_sim],\n",
    "  title = \"Best and worst qubit pair for: \" + backend.name(),\n",
    "  legend     = [\"Worst qubit pair\",\"Best qubit pair\",\"Simulated baseline\"],             \n",
    "  sort       = 'desc',\n",
    "  figsize    = (15,12),\n",
    "  color      = ['red','green', 'blue'],\n",
    "  bar_labels = True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
